package com.devunion.bogdan.view;

import com.devunion.bogdan.view.actions.ActionManager;
import com.devunion.bogdan.view.swixml.CustomSwingEngine;
import com.devunion.bogdan.view.toolbar.ToolbarManager;
import com.devunion.bogdan.view.project.PageNode;
import com.devunion.bogdan.model.project.*;
import com.devunion.bogdan.model.event.ProjectEvent;
import com.devunion.bogdan.model.event.ProjectListener;
import com.devunion.bogdan.model.event.UserListener;
import com.devunion.bogdan.model.event.UserEvent;
import com.devunion.bogdan.model.UserManager;

import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.net.URL;
import java.util.Locale;

import org.apache.log4j.Logger;

/**
 * @author Leska
 */

public class LibrarianEditor extends JFrame {
    private CustomSwingEngine se = new CustomSwingEngine(ActionManager.getInstance());

    private static LibrarianEditor instance;

    private ContentPane contentPane;
    private BasicWorkspace selectedWorkspace;

    /**
     * Creates new form DefaultEditor
     */
    private LibrarianEditor() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);


        ProjectManager.getInstance().addProjectListener(new ProjectListener() {
            public void projectCreated(ProjectEvent e) {
                contentPane.showWorkingPanel(e.getProject());
            }

            public void projectClosed(ProjectEvent e) {
                contentPane.closeCurrentWorkingPanel();
            }
        });

        initComponents();

//        addWindowListener(new WindowAdapter() {
//            public void windowDeactivated(WindowEvent e) {
//                try {
//                    ProjectManager.getInstance().saveCurrentProject();
//                } catch (ProjectSavingException e1) {
//                    log.error(e1.getMessage(), e1);
//                }
//            }
//        });
    }

    public static LibrarianEditor getInstance() {
        if (instance == null) {
            instance = new LibrarianEditor();
        }

        return instance;
    }

    public BasicWorkspace getSelectedWorkspace() {
        return selectedWorkspace;
    }

    private void initComponents() {
        setTitle("Librarian Editor Tool v. 0.0.2");


        try {
            URL mainToolbarDefinition = LibrarianEditor.class.getResource("/com/devunion/bogdan/conf/toolbar.xml");
            URL editorToolbarDefinition = LibrarianEditor.class.getResource("/com/devunion/bogdan/conf/editor-toolbar.xml");

            se.setLocale(Locale.ENGLISH);

            Container mainToolbar = se.render(mainToolbarDefinition);
            Container editorToolbar = se.render(editorToolbarDefinition);

            ToolbarManager.getInstance().setEditorToolbar(editorToolbar);
            ToolbarManager.getInstance().setMainToolbar(mainToolbar);

            contentPane = new ContentPane();
            contentPane.addToolbar(mainToolbar);
            contentPane.addToolbar(editorToolbar);

            setJMenuBar(createMenuBar());
        } catch (Exception e) {
            e.printStackTrace();
        }
        setContentPane(contentPane);

        setPreferredSize(new Dimension(800, 600));
        pack();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private JMenuBar createMenuBar() throws Exception {

        URL menubarDefinition = LibrarianEditor.class.getResource("/com/devunion/bogdan/conf/menu.xml");
        JMenuBar menuBar = (JMenuBar) se.render(menubarDefinition);

//        for (Component c : menuBar.getComponents()) {
//            if ("fileMenu".equals(c.getName())) {
//                for (Component m : ((JMenu) c).getMenuComponents()) {
//                    if ("reopenMenu".equals(m.getName())) {
//                        addRecentProjects((JMenu) m);
//                    }
//                }
//            }
//        }
//
        return menuBar;
    }

    public void showWindow() {
        setVisible(true);
    }

    private class ContentPane extends JPanel {
        private Logger log = Logger.getLogger(ContentPane.class);

        private JPanel toolbarPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        private JTabbedPane jTabbedPane = new JTabbedPane();

        private PaperOpeningListener paperOpeningListener;

        public ContentPane() {
            super(new BorderLayout());

            paperOpeningListener = new PaperOpeningListener() {
                public void openPaper(Paper p) {
                    openPaperInNewTab(p);
                }

                public void openProject(Project p) {
                    openProjectInNewTab(p);
                }
            };

            final SearchProjectsPanel projectsPanel = new SearchProjectsPanel();
            projectsPanel.setPaperOpeningListener(paperOpeningListener);

            UserManager.getInstance().addUserListener(new UserListener() {
                public void userLoggedIn(UserEvent e) {

                    if (jTabbedPane.getSelectedIndex() == 0 || e.getUser() == null) {
                        ActionManager.getInstance().deleteProjectAction.setEnabled(false);
                        return;
                    }

                    final BasicWorkspace workspace = (BasicWorkspace) jTabbedPane.getSelectedComponent();
                    boolean canDelete = e.getUser().getRole() == UserRole.ADMIN ||
                            (e.getUser().getRole() == UserRole.EXPERT && workspace.getProject().getOwner().getLogin().equals(e.getUser().getLogin()));

                    ActionManager.getInstance().deleteProjectAction.setEnabled(canDelete);
                }
            });

            jTabbedPane.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    if (((JTabbedPane) e.getSource()).getSelectedIndex() == 0) {
                        LibrarianEditor.this.selectedWorkspace = null;

                        ProjectManager.getInstance().setCurrentProject(null);
                        ActionManager.getInstance().update(false);

                        ActionManager.getInstance().deleteProjectAction.setEnabled(false);
                        ToolbarManager.getInstance().setEditorToolbarVisible(false);

                    } else {
                        final BasicWorkspace workspace = (BasicWorkspace) ((JTabbedPane) e.getSource()).getSelectedComponent();
                        LibrarianEditor.this.selectedWorkspace = workspace;
                        workspace.onSelected();

                        ProjectManager.getInstance().setCurrentProject(workspace.getProject());
                        ActionManager.getInstance().update(true);

                        boolean canDelete = UserManager.getInstance().getUser() != null &&
                                UserManager.getInstance().getUser().getRole() == UserRole.ADMIN;
                        ActionManager.getInstance().deleteProjectAction.setEnabled(canDelete);

                        JTree tree = workspace.getProjectTreeBrowser().getProjectTree();
                        if (tree == null) {
                            workspace.getProjectTreeBrowser().openProject(workspace.getProject());

                            tree = workspace.getProjectTreeBrowser().getProjectTree();
                        }

                        final Object selection = tree.getLastSelectedPathComponent();

                        if (selection instanceof PageNode) {
                            ToolbarManager.getInstance().setEditorToolbarVisible(true);
                        }
                    }
                }
            });

            jTabbedPane.addTab("Search", projectsPanel);

//            showWorkingPanel(p.get);

            add(toolbarPanel, BorderLayout.NORTH);
            add(jTabbedPane, BorderLayout.CENTER);
        }

        private void openPaperInNewTab(Paper p) {

            int tabsCount = jTabbedPane.getTabCount();

            Project project = ProjectManager.getInstance().getProjectForPaper(p.getPaperId());

            for (int i = 1; i < tabsCount; i++) {
                final BasicWorkspace workspace = (BasicWorkspace) jTabbedPane.getComponentAt(i);

                if (workspace.getProject().getProjectId() == project.getProjectId()) {

                    if (!workspace.getProject().getEntries().contains(p)) {
                        workspace.getProject().addEntry(p);
                    }
                    return;
                }
            }

            try {
                ProjectManager.getInstance().loadProject(project);
            } catch (ProjectLoadingException e) {
                log.error(e);
            }
        }

        private void openProjectInNewTab(Project project) {

            int tabsCount = jTabbedPane.getTabCount();

            for (int i = 1; i < tabsCount; i++) {
                final BasicWorkspace workspace = (BasicWorkspace) jTabbedPane.getComponentAt(i);

                if (workspace.getProject().getProjectId() == project.getProjectId()) {
                    return;
                }
            }

            try {
                ProjectManager.getInstance().loadProject(project);
            } catch (ProjectLoadingException e) {
                log.error(e);
            }
        }

        public void addToolbar(Component toolbar) {
            toolbarPanel.add(toolbar);
        }

        public void closeCurrentWorkingPanel() {
            if (LibrarianEditor.this.selectedWorkspace != null) {
                jTabbedPane.remove(LibrarianEditor.this.selectedWorkspace);
            }
        }

        public void showWorkingPanel(Project project) {

            final BasicWorkspace workspace = new BasicWorkspace(project);
            workspace.setPaperOpeningListener(paperOpeningListener);

            jTabbedPane.addTab(project.getName(), workspace);

            workspace.onActive();

            jTabbedPane.setSelectedComponent(workspace);

            toolbarPanel.setVisible(true);
            ToolbarManager.getInstance().setEditorToolbarVisible(false);
            ToolbarManager.getInstance().setMainToolbarVisible(true);
        }
    }
}
